package com.syqc.monitor.ui.simplemonitor

import android.Manifest
import android.content.Intent
import android.text.Html
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.text.HtmlCompat
import androidx.core.view.GravityCompat
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import autodispose2.autoDispose
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.module.DraggableModule
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.guanaj.easyswipemenulibrary.EasySwipeMenuLayout
import com.gyf.immersionbar.ktx.immersionBar
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.permissionx.guolindev.PermissionX
import com.syqc.monitor.ui.carinfo.CarInfoActivity
import com.syqc.choose.team.ChooseTeamActivity
import com.syqc.choose.teamcar.TeamsActivity
import com.syqc.comlib.GuideControl.isSimpleMonitor
import com.syqc.comlib.UserConstant
import com.syqc.comlib.base.BaseActivity
import com.syqc.comlib.callback.EmptyCallback
import com.syqc.comlib.rx.doAfterChanged
import com.syqc.comlib.rx.filterFast
import com.syqc.comlib.utils.ActivityResultUtil.launchAct
import com.syqc.comlib.utils.ActivityResultUtil.registerResultOk
import com.syqc.comlib.utils.loadStringDImgError
import com.syqc.comlib.utils.startActivityTo
import com.syqc.comlib.utils.sub
import com.syqc.comlib.utils.subPlate
import com.syqc.comlib.utils.toast
import com.syqc.entity.GpsDetail
import com.syqc.login.LocationStatusModel
import com.syqc.monitor.R
import com.syqc.monitor.databinding.ActivityMonitorListSimpleBinding
import com.syqc.monitor.databinding.IncludeListMonitorToolbarBinding
import com.syqc.monitor.databinding.IncludeMonitorEndBinding
import com.syqc.monitor.ui.alarm.NormalAlarmActivity
import com.syqc.monitor.ui.carmonitor.CarMonitorActivity
import com.syqc.monitor.ui.historyline.HistoryLineActivity
import com.syqc.monitor.ui.list.ListItemPopup
import com.syqc.monitor.ui.mile.MileActivity
import com.syqc.monitor.ui.photo.PhotosActivity
import com.syqc.monitor.ui.stopcar.StopCarActivity
import com.syqc.utils.Keys
import com.syqc.utils.NetDataUtil
import com.syqc.utils.ToolsUtil
import com.syqc.utils.ToolsUtil.stateColor
import com.syqc.utils.Units
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers

/**
 *@Author Jasper
 *@Time   2021/3/16
 *@Desc   极简监控
 */
class SimpleMonitorActivity :
    BaseActivity<ActivityMonitorListSimpleBinding>(ActivityMonitorListSimpleBinding::inflate) {
    private var isRefresh = false
    private lateinit var mListMonitorVB: IncludeMonitorEndBinding
    private lateinit var mMonitorBarVB: IncludeListMonitorToolbarBinding
    private lateinit var loadService: LoadService<Any>
    private var locationEntity: GpsDetail? = null

    private var mCarPopup: SimpleMonitorPopup? = null

    private val mAdapter by lazy {
        MAdapter()
    }
    private val itemPopup: ListItemPopup by lazy {
        ListItemPopup(this, true, clickListener)
    }

    private val mViewModel by viewModels<SimpleMonitorViewModel>()

    /**
     * 初始化界面
     */
    override fun initView() {
        loadService = LoadSir.getDefault().register(binding.recyclerView)
        mListMonitorVB = IncludeMonitorEndBinding.bind(binding.root)
        mMonitorBarVB = IncludeListMonitorToolbarBinding.bind(binding.root)
        immersionBar { titleBar(mMonitorBarVB.listToolbar) }
        loadService.showCallback(EmptyCallback::class.java)

        mMonitorBarVB.tvToolbarTitle.setText(R.string.title_monitor_list_simple)

        if (UserConstant.current_car_num > 300) {

            if (NetDataUtil.isSyncTree) {
                launcher.launchAct<TeamsActivity>(this) {
                    putExtra("isMap", true)
                }
            } else {
                launcher.launchAct<ChooseTeamActivity>(this) {
                    putExtra("isMap", true)
                }
            }
            mListMonitorVB.tvListAllCars.isVisible = false
        } else {
            mMonitorBarVB.tvToolbarTitle.setText(R.string.desc_map_all_car)
            mViewModel.getCarsLocation()
        }

        initEndView()
        binding.recyclerView.layoutManager = LinearLayoutManager(this)
        binding.recyclerView.adapter = mAdapter

        mViewModel.toastObserver().observeOn(AndroidSchedulers.mainThread())
            .autoDispose(scopeProvider).subscribe(::toastObserver)

        mViewModel.carsObserver().observeOn(AndroidSchedulers.mainThread())
            .autoDispose(scopeProvider).subscribe {
                if (it.isNullOrEmpty()) {
                    loadService.showCallback(EmptyCallback::class.java)
                } else {
                    if (isRefresh) toast(R.string.toast_refresh_success)
                    isRefresh = false
                    loadService.showSuccess()
                    mAdapter.setList(it)
                }
            }
        binding.root.postDelayed({
            if (isSimpleMonitor) {
                isSimpleMonitor = false
                mCarPopup = SimpleMonitorPopup(this)
                mCarPopup?.showAtLocation(binding.root, Gravity.NO_GRAVITY, 0, 0)
            }
        }, 300)

    }


    override fun setListener() {
        mMonitorBarVB.ivToolbarStart.setOnClickListener {
            if (isHome) {
                startHomeActivity()
            }
            finish()
        }

        mMonitorBarVB.ivToolbarCenter.filterFast {
            mViewModel.getCarsLocation()
            isRefresh = true
        }

        mMonitorBarVB.ivToolbarEnd.setOnClickListener {
            if (binding.listDrawerLayout.isDrawerOpen(GravityCompat.END)) {
                binding.listDrawerLayout.closeDrawer(GravityCompat.END)
            } else {
                binding.listDrawerLayout.openDrawer(GravityCompat.END)
            }
        }

        mListMonitorVB.tvListChooseCar.filterFast {
            binding.listDrawerLayout.closeDrawer(GravityCompat.END)

            if (NetDataUtil.isSyncTree) {
                launcher.launchAct<TeamsActivity>(this) {
                    putExtra("isMap", true)
                }
            } else {
                launcher.launchAct<ChooseTeamActivity>(this) {
                    putExtra("isMap", true)
                }
            }
        }
        mListMonitorVB.tvListClear.filterFast {
            mMonitorBarVB.tvToolbarTitle.setText(R.string.title_monitor_list_simple)
            mViewModel.teamId = ""
            mAdapter.setList(null)
            mViewModel.isClear = true
            loadService.showCallback(EmptyCallback::class.java)
        }
        mListMonitorVB.tvListAllCars.filterFast {
            binding.listDrawerLayout.closeDrawer(GravityCompat.END)
            mMonitorBarVB.tvToolbarTitle.setText(R.string.desc_map_all_car)
            mViewModel.teamId = ""
            mViewModel.isClear = false
            mViewModel.getCarsLocation()
        }
        mListMonitorVB.rdbListPlate.filterFast {
            mListMonitorVB.rdbListPlate.isChecked = true
            mViewModel.sortByType = "carPlate"
            mAdapter.isPlate = true
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.rdbListCarName.filterFast {
            mListMonitorVB.rdbListCarName.isChecked = true
            mViewModel.sortByType = "carName"
            mAdapter.isPlate = false
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.cbListTime.isVisible = false

        mListMonitorVB.cbListState.filterFast {
            mListMonitorVB.cbListState.isSelected = !SimpleMonitorModel.instance.getStateShow()
            SimpleMonitorModel.instance.setState(mListMonitorVB.cbListState.isSelected)
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.cbListSpeed.filterFast {
            mListMonitorVB.cbListSpeed.isSelected = !SimpleMonitorModel.instance.getSpeedShow()
            SimpleMonitorModel.instance.setSpeed(mListMonitorVB.cbListSpeed.isSelected)
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.cbListDriver.filterFast {
            mListMonitorVB.cbListDriver.isSelected = !SimpleMonitorModel.instance.getDriverShow()
            SimpleMonitorModel.instance.setDriver(mListMonitorVB.cbListDriver.isSelected)
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.cbListMile.filterFast {
            mListMonitorVB.cbListMile.isSelected = !SimpleMonitorModel.instance.getMileShow()
            SimpleMonitorModel.instance.setMile(mListMonitorVB.cbListMile.isSelected)
            mAdapter.notifyDataSetChanged()
        }
        mListMonitorVB.cbListRunStop.filterFast {
            mListMonitorVB.cbListRunStop.isSelected = !SimpleMonitorModel.instance.getRunStopShow()
            SimpleMonitorModel.instance.setRunStop(mListMonitorVB.cbListRunStop.isSelected)
            mAdapter.notifyDataSetChanged()
        }
        //////////
        mListMonitorVB.cbOil.filterFast {
            mListMonitorVB.cbOil.isSelected = !SimpleMonitorModel.instance.getOilShow()
            SimpleMonitorModel.instance.setOilShow(mListMonitorVB.cbOil.isSelected)
            mAdapter.notifyDataSetChanged()
        }

        mListMonitorVB.cbWater.filterFast {
            mListMonitorVB.cbWater.isSelected = !SimpleMonitorModel.instance.getWaterShow()
            SimpleMonitorModel.instance.setWaterShow(mListMonitorVB.cbWater.isSelected)
            mAdapter.notifyDataSetChanged()
        }

        mListMonitorVB.cbTemp.filterFast {
            mListMonitorVB.cbTemp.isSelected = !SimpleMonitorModel.instance.getTempShow()
            SimpleMonitorModel.instance.setTempShow(mListMonitorVB.cbTemp.isSelected)
            mAdapter.notifyDataSetChanged()
        }

        mListMonitorVB.cbDamp.filterFast {
            mListMonitorVB.cbDamp.isSelected = !SimpleMonitorModel.instance.getDempShow()
            SimpleMonitorModel.instance.setDempShow(mListMonitorVB.cbDamp.isSelected)
            mAdapter.notifyDataSetChanged()
        }

        mListMonitorVB.cbLoad.filterFast {
            mListMonitorVB.cbLoad.isSelected = !SimpleMonitorModel.instance.getLoadShow()
            SimpleMonitorModel.instance.setLoadShow(mListMonitorVB.cbLoad.isSelected)
            mAdapter.notifyDataSetChanged()
        }


        binding.listDrawerLayout.addDrawerListener(object : DrawerLayout.SimpleDrawerListener() {
            override fun onDrawerClosed(drawerView: View) {
                super.onDrawerClosed(drawerView)
                mMonitorBarVB.ivToolbarCenter.isSelected = false
            }

            override fun onDrawerOpened(drawerView: View) {
                super.onDrawerOpened(drawerView)
                mMonitorBarVB.ivToolbarCenter.isSelected = true
            }
        })

        binding.ivClear.setOnClickListener {
            binding.editSearch.setText("")
        }

        binding.tvSearch.setOnClickListener {
            mViewModel.search(binding.editSearch.text.toString(), mAdapter.isPlate)
        }

        binding.editSearch.doAfterChanged {
            if (it.isNullOrEmpty()) {
                mViewModel.setAllData()
            }
            binding.ivClear.isInvisible = it.isNullOrEmpty()
        }

    }

    private fun initEndView() {
        mListMonitorVB.rdbListPlate.isChecked = mViewModel.sortByType == "carPlate"
        mListMonitorVB.rdbListCarName.isChecked = mViewModel.sortByType == "carName"
        mListMonitorVB.cbListTime.isSelected = SimpleMonitorModel.instance.getTimeShow()
        mListMonitorVB.cbListState.isSelected = SimpleMonitorModel.instance.getStateShow()
        mListMonitorVB.cbListSpeed.isSelected = SimpleMonitorModel.instance.getSpeedShow()
        mListMonitorVB.cbListDriver.isSelected = SimpleMonitorModel.instance.getDriverShow()
        mListMonitorVB.cbListMile.isSelected = SimpleMonitorModel.instance.getMileShow()
        mListMonitorVB.cbListRunStop.isSelected = SimpleMonitorModel.instance.getRunStopShow()
        mAdapter.isPlate = mListMonitorVB.rdbListPlate.isChecked
        mListMonitorVB.cbOil.isSelected = SimpleMonitorModel.instance.getOilShow()
        mListMonitorVB.cbWater.isSelected = SimpleMonitorModel.instance.getWaterShow()
        mListMonitorVB.cbTemp.isSelected = SimpleMonitorModel.instance.getTempShow()
        mListMonitorVB.cbDamp.isSelected = SimpleMonitorModel.instance.getDempShow()
        mListMonitorVB.cbLoad.isSelected = SimpleMonitorModel.instance.getLoadShow()
    }

    private val clickListener = View.OnClickListener { v ->
        if (locationEntity == null || ToolsUtil.isFastClick()) return@OnClickListener
        when (v.id) {
            R.id.tvLMPopSingleCar -> {
                when (locationEntity!!.state) {
                    "1", "5" -> toast(R.string.toast_car_state_no_location)
                    else -> startToCarMonitor()
                }
            }

            R.id.tvLMPopLine -> {
                startActivity(HistoryLineActivity::class.java)
            }

            R.id.tvLMPopInfo -> {
                startActivity(
                    Intent(this, CarInfoActivity::class.java).putExtra(
                        Keys.INTENT_CAR_ID,
                        locationEntity!!.carId
                    )
                )
            }

            R.id.tvLMPopMile -> {
                startActivity(MileActivity::class.java)
            }

            R.id.tvLMPopAlarm -> {
                startActivity(NormalAlarmActivity::class.java)
            }

            R.id.tvLMPopPhoto -> {
                startActivity(PhotosActivity::class.java)
            }

            R.id.tvLMPopStopCar -> {
                startActivity(StopCarActivity::class.java)
            }
        }
    }

    private fun startActivity(zClass: Class<*>) {
        startActivity(
            Intent(this, zClass)
                .putExtra(Keys.INTENT_CAR_ID, locationEntity!!.carId)
                .putExtra(Keys.INTENT_IS_VIDEO, locationEntity!!.videos)
                .putExtra(Keys.INTENT_PLATE, subPlate(locationEntity!!.carPlate, 14))
        )
    }


    private fun startToCarMonitor() {
        PermissionX.init(this).permissions(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ).request { allGranted, grantedList, deniedList ->
            if (allGranted) {
                startActivityTo<CarMonitorActivity>(this) {
                    putExtra(Keys.INTENT_CAR_ID, locationEntity!!.carId)
                    putExtra(Keys.INTENT_IS_VIDEO, locationEntity!!.videos)
                    putExtra(Keys.INTENT_PLATE, subPlate(locationEntity!!.carPlate, 14))
                }
            } else {
                getString(
                    R.string.toast_persission_open, getString(R.string.permission_location)
                ).toast(this)
            }
        }
    }


    private val launcher = registerResultOk { result ->
        result.data?.let {
            val teamId = it.getStringExtra(Keys.INTENT_TEAM_ID) ?: ""
            val teamName = it.getStringExtra(Keys.INTENT_TEAM_NAME) ?: ""
            mViewModel.teamId = teamId
            mViewModel.isClear = false
            mViewModel.getCarsLocation()
            binding.listDrawerLayout.closeDrawers()
            mMonitorBarVB.tvToolbarTitle.text = "${sub(teamName, 10)}"
        }
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (binding.listDrawerLayout.isDrawerOpen(GravityCompat.END)) {
            binding.listDrawerLayout.closeDrawer(GravityCompat.END)
            return false
        }
        return super.onKeyDown(keyCode, event)
    }


    private inner class MAdapter :
        BaseQuickAdapter<GpsDetail, BaseViewHolder>(R.layout.item_simple_monitor),
        DraggableModule {
        var isPlate = true
        override fun convert(holder: BaseViewHolder, item: GpsDetail) {
            item.run {
                holder.setText(
                    R.id.tv_simple_title,
                    subPlate(if (isPlate) carPlate else carName, 14)
                )
                val imageView: ImageView = holder.getView(R.id.iv_simple_car)
                imageView.loadStringDImgError(context, iconLink)

                val driverName =
                    if (drvSign.isNullOrEmpty()) context.getString(R.string.desc_driver_no) else drvSign
                val st1V = LocationStatusModel.getDesc(st1)
                val st3V = LocationStatusModel.getDesc(st3)
                val st2V = LocationStatusModel.getDesc(st2)
                val st5V = LocationStatusModel.getDesc(st5)
                val st4V = LocationStatusModel.getDesc(st4)
                val speed =
                    if (SimpleMonitorModel.instance.getSpeedShow()) setColor("${speed}${Units.speed} | ") else ""
                val stateText = "<font color=${stateColor(item.state)} >${item.stateCn}</font>"
                val other =
                    (if (SimpleMonitorModel.instance.getDriverShow()) "$driverName | " else "") +
                            (if (SimpleMonitorModel.instance.getMileShow()) "${preMile}${Units.km} | ${mile}${Units.km} | " else "") +
                            (if (SimpleMonitorModel.instance.getRunStopShow()) "$runStopTime | " else "") +
                            (if (SimpleMonitorModel.instance.getOilShow() && st1V.isNotEmpty()) "$st1V | " else "") +
                            (if (SimpleMonitorModel.instance.getTempShow() && st3V.isNotEmpty()) "$st3V | " else "") +
                            (if (SimpleMonitorModel.instance.getLoadShow() && st2V.isNotEmpty()) "$st2V | " else "") +
                            (if (SimpleMonitorModel.instance.getWaterShow() && st5V.isNotEmpty()) "$st5V | " else "") +
                            (if (SimpleMonitorModel.instance.getDempShow() && st4V.isNotEmpty()) "$st4V | " else "") +
                            addr
                val state = if (SimpleMonitorModel.instance.getStateShow()) "$stateText | " else ""
                val info = "$speed$state${setColor(other)}"

                holder.setText(
                    R.id.tv_simple_info,
                    Html.fromHtml(info, HtmlCompat.FROM_HTML_MODE_LEGACY)
                )
                    .setText(R.id.tv_simple_time, time)

                holder.getView<TextView>(R.id.tv_simple_delete).setOnClickListener { v ->
                    data.removeAt(holder.layoutPosition)
                    notifyItemRemoved(holder.layoutPosition)
                    val view: EasySwipeMenuLayout = holder.getView(R.id.easy_swipe)
                    view.resetStatus()
                }
                val content = holder.getView<LinearLayout>(R.id.content)
                content.setBackgroundResource(ToolsUtil.getListBgRes(state))
                content.setOnClickListener {
                    locationEntity = item
                    itemPopup.showAtLocation(
                        window.decorView,
                        sub(
                            if (isPlate) {
                                item.carPlate
                            } else {
                                item.carName
                            }, 10
                        )
                    )
                }
            }
        }

        fun setColor(state: String): String {
            return "<font color='#666666'> $state</font>"
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mCarPopup != null && mCarPopup?.isShowing == true) {
            mCarPopup?.dismiss()
            mCarPopup = null
        }
    }
}
